<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Start.aspx.cs" Inherits="HaversineDistance.Start" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" />
  <!-- link href="Stylesheet.css" type="text/css" rel="Stylesheet" /-->
  <title>Haversine Distance</title>
  
  <style media="screen">
  
      div.header
    {
	    padding-bottom:10px;
    }

    div.footnote
    {	
	    padding-top:9px;
	    font-size:smaller;
    }

    div.errorSummary
    {
	    padding:5px;
	    color:Red;
    }
  </style>
  
  
  
    <script type="text/javascript">
  
    function JSDistanceCalc() {

      var lat1 = document.getElementById("inputLat1");
      var lat2 = document.getElementById("inputLat2");
      var long1 = document.getElementById("inputLong1");
      var long2 = document.getElementById("inputLong2");

      // reset border color, may be red if there was a previous validation error
      lat1.style.borderColor = '';
      lat2.style.borderColor = '';
      long1.style.borderColor = '';
      long2.style.borderColor = '';

      if (ValidateCoordinates(lat1, lat2, long1, long2)) {

   			var RadiusOfEarthMiles = 3959.0;
   			var RadiusOfEarthKilometers = 6378.1;
   			
   			var milesDistance = CalcHaversineDistance(lat1.value, lat2.value, long1.value, long2.value, RadiusOfEarthMiles);
   			var kilosDistance = CalcHaversineDistance(lat1.value, lat2.value, long1.value, long2.value, RadiusOfEarthKilometers);

        var span = document.getElementById('spanDistance');
        span.innerHTML = milesDistance.toFixed(2) + ' miles /' + kilosDistance.toFixed(2) + ' km';
                
      }
    }

    function CalcHaversineDistance(lat1, lat2, long1, long2, radius) {

      var radianLat1 = ToRadians(lat1);
			var radianLong1 = ToRadians(long1);
			var radianLat2 = ToRadians(lat2);
			var radianLong2 = ToRadians(long2);
			var radianDistanceLat = radianLat1 - radianLat2;
			var radianDistanceLong = radianLong1 - radianLong2;
			var sinLat = Math.sin(radianDistanceLat / 2.0);
			var sinLong = Math.sin(radianDistanceLong / 2.0);
			var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLong, 2.0);
			var distance = radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));

			return distance;
	  }

	  function ToRadians(degree) {
	    return (degree * (Math.PI / 180));
	  }

    function ValidateCoordinates(lat1, lat2, long1, long2) {

      var div = document.getElementById('validationErrors');

      var latErrorMessage = '';
      var longErrorMessage = '';
      var ret = true;

      if (!validLat(lat1.value)) {
        lat1.style.borderColor = 'Red';
        latErrorMessage = 'Latitude must be a numeric value between 90 and -90 <br />';
        ret = false;
      }
      
      if (!validLat(lat2.value)) {
        lat2.style.borderColor = 'Red';
        latErrorMessage = 'Latitude must be a numeric value between 90 and -90 <br />';
        ret = false;
      }

      if (!validLat(long1.value)) {
        long1.style.borderColor = 'Red';
        longErrorMessage = 'Longitude must be a numeric value between 180 and -180';
        ret = false;
      }

      if (!validLat(long2.value)) {
        long2.style.borderColor = 'Red';
        longErrorMessage = 'Longitude must be a numeric value between 180 and -180';
        ret = false;
      }

      var div = document.getElementById('validationErrors');
      div.innerHTML = latErrorMessage + longErrorMessage;

      return ret;
    }

    function validLat(lat) {
      if (lat.trim() != '') {
        return ((lat >= -90) && (lat <= 90));
      }
      return false;
    }

    String.prototype.trim = function() {
      a = this.replace(/^\s+/, '');
      return a.replace(/\s+$/, '');
    };    
  
  </script>
  
  
</head>
<body>
    <form id="form1" runat="server">
    <div class="header">      
    This page uses the <a href="http://en.wikipedia.org/wiki/Haversine_formula" target="_blank">Haversine Formula</a> 
    to find the great-circle distance between two points on 
      the earth. The points are a pair of lat/long coordinates entered as decimal 
      degrees (DD).
    <div class="errorSummary">
      <asp:ValidationSummary ID="vsErrors" runat="server" DisplayMode="BulletList" /></div>
      <asp:CustomValidator ID="cvLatitude" runat="server" Display="None" 
        ErrorMessage="Latitude must be a numeric value between 90 and -90" 
        onservervalidate="cvLatitude_ServerValidate" />
      <asp:CustomValidator ID="cvLongitude" runat="server" Display="None" 
        ErrorMessage="Longitude must be a numeric value between 180 and -180" 
        onservervalidate="cvLongitude_ServerValidate" />
    </div>
    <table border="1">
      <tr><td colspan="3">The values in this table are posted back to the server, <br />
              which calculates the distance and displays it in the table footer.</td></tr>
      <tr>
        <td></td>
        <td>Latitude*</td><td>Longitude**</td>
      </tr>
      <tr>
        <td>Point 1</td>
        <td><asp:TextBox runat="server" ID="txtLat1" /></td>
        <td><asp:TextBox runat="server" ID="txtLong1" /></td>
      </tr>
      <tr>
        <td>Point 2</td>
        <td><asp:TextBox runat="server" ID="txtLat2" /></td>
        <td><asp:TextBox runat="server" ID="txtLong2" /></td>
      </tr>
      <tr>
        <td>Distance</td>
        <td><asp:Label runat="server" ID="lblDistance" /></td>
        <td align="right"><asp:Button runat="server" ID="btnCalculate" Text="Go (postback)" OnClick="btnCalculate_OnClick" /></td>
      </tr>
    </table>
    <div class="footnote">
      * For south latitudes put a "-" before the value, e.g. -12.7665<br />
      ** For west longitudes put a "-" before the value, e.g. -102.5332
    </div>
    <br /><br /><br />
    <div class="errorSummary" id="validationErrors"></div>    
    <table border="1">
      <tr><td colspan="3">In this table, the calculation is done with javascript in the client's browser.<br /></td></tr>
      <tr>
        <td></td>
        <td>Latitude*</td><td>Longitude**</td>
      </tr>
      <tr>
        <td>Point 1</td>
        <td><input type="text" id="inputLat1" /></td>
        <td><input type="text" id="inputLong1" /></td>
      </tr>
      <tr>
        <td>Point 2</td>
        <td><input type="text" id="inputLat2" /></td>
        <td><input type="text" id="inputLong2" /></td>
      </tr>
      <tr>
        <td>Distance</td>
        <td><span id="spanDistance"></span></td>
        <td align="right"><input type="button" value="Go (javascript)" onclick="javascript:JSDistanceCalc();" /></td>
      </tr>
    </table>
    <div class="footnote">
      * For south latitudes put a "-" before the value, e.g. -12.7665<br />
      ** For west longitudes put a "-" before the value, e.g. -102.5332
    </div>
    </form>
</body>
</html>
